package com.sparrow.common.util;

import org.quartz.CronExpression;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class CronUtil {
    // SLF4J 日志记录器
    private static final Logger LOGGER = LoggerFactory.getLogger(CronUtil.class);

    public static void main(String[] args) {
        try {
            long result = parse("0 0 * * * ?", System.currentTimeMillis());
            System.out.println("Next valid timestamp: " + result);

            boolean isValid = isValidCronExpression("0 0 * * * ?");
            System.out.println("Is valid cron expression: " + isValid);

            List<Date> nextExecutionTimes = getNextExecutionTimes("0 0 * * * ?", 3, new Date());
            for (Date time : nextExecutionTimes) {
                System.out.println("Next execution time: " + time);
            }
        } catch (RuntimeException e) {
            LOGGER.error("Error occurred while processing cron expression", e);
        }
    }

    /**
     * 解析 cron 表达式，获取指定时间戳之后的下一个有效时间戳。
     *
     * @param cronExpression cron 表达式
     * @param timestamp      起始时间戳
     * @return 下一个有效时间的时间戳
     * @throws RuntimeException 如果 cron 表达式解析失败
     */
    public static long parse(String cronExpression, long timestamp) {
        try {
            // 创建 CronExpression 对象
            CronExpression exp = new CronExpression(cronExpression);
            // 获取指定时间之后的下一个有效时间
            Date date = exp.getNextValidTimeAfter(new Date(timestamp));
            if (date == null) {
                LOGGER.warn("No valid time found for cron expression: {}", cronExpression);
                return -1;
            }
            return date.getTime();
        } catch (java.text.ParseException ex) {
            // 记录错误日志
            LOGGER.error("Failed to parse cron expression: {}", cronExpression, ex);
            // 抛出运行时异常
            throw new RuntimeException("Invalid cron expression: " + cronExpression, ex);
        }
    }

    /**
     * 验证 Cron 表达式是否合法
     *
     * @param cronExpression 待验证的 Cron 表达式
     * @return 如果表达式合法返回 true，否则返回 false
     */
    public static boolean isValidCronExpression(String cronExpression) {
        try {
            new CronExpression(cronExpression);
            return true;
        } catch (ParseException e) {
            LOGGER.error("Invalid cron expression: {}", cronExpression, e);
            return false;
        }
    }

    /**
     * 获取 Cron 表达式的下 N 个执行时间
     *
     * @param cronExpression  Cron 表达式
     * @param numberOfTimes 要获取的执行时间数量
     * @param startTime 开始时间
     * @return 包含下 N 个执行时间的列表
     */
    public static List<Date> getNextExecutionTimes(String cronExpression, int numberOfTimes, Date startTime) {
        List<Date> nextExecutionTimes = new ArrayList<>();
        try {
            CronExpression exp = new CronExpression(cronExpression);
            Date nextTime = startTime;
            for (int i = 0; i < numberOfTimes; i++) {
                nextTime = exp.getNextValidTimeAfter(nextTime);
                if (nextTime == null) {
                    break;
                }
                nextExecutionTimes.add(nextTime);
            }
        } catch (ParseException e) {
            LOGGER.error("Error parsing cron expression: {}", cronExpression, e);
        }
        return nextExecutionTimes;
    }
}